<?php

namespace app\api\controller;

use app\admin\model\Third;
use app\admin\model\User;
use app\common\controller\Api;
use app\common\library\wxpay\WechatPay;
use app\common\library\Payment;
use app\common\model\Config;
use app\common\model\Order;
use app\common\model\OrderThird;
use app\common\model\Store;
use think\Db;
use think\Exception;

/**
 * Ticket接口
 * 用户打榜
 */
class Ticket extends Api
{
    protected $noNeedLogin = ['get_store_list', 'get_ticket_user_list', 'pay_notify'];
//    protected $noNeedLogin = ['*'];
    protected $noNeedRight = ['*'];

    /**
     * 分会打榜排名列表
     */
    public function get_store_list(){
        $page = $this->request->param('page') ?: 1;
        $time = $this->request->param('time', '');
        if(empty($time)){
            $time = strtotime(date('Y-m-d'));
        }

        $list = Store::alias('s')
            ->join('Order o', 's.id = o.store_id AND o.is_cancel = '.Order::IS_CANCEL_NOT.' AND o.is_paid = '.Order::IS_PAID_PAY.' AND o.createtime < '.$time, 'left')
            ->field('s.id,s.name,s.logo,count(o.id) as ticket, sum(o.money) as money')
            ->where('s.if_ticket', Store::IF_TICKET_YES)
            //->field('s.id,s.name,s.logo,ticket, ticket_money as money')
            ->order('ticket desc,s.weigh desc,s.id asc')
            ->group('s.id')
            ->paginate($this->pagenum);
        //(SELECT count(*) FROM (SELECT bin_order.store_id, bin_order.user_id FROM bin_order GROUP BY bin_order.store_id, bin_order.user_id ) AS a WHERE a.store_id = s.id GROUP BY a.store_id) AS ticket_user
        $offset = $this->pagenum * ($page - 1) + 1;
        foreach($list as &$item){
            $item['money'] = $item['money'] ?: 0;
            $item['rank'] = $offset;
            $item['logo'] = getRealImg($item['logo']);
            $offset++;
        }
        $this->success('获取成功', $list);
    }

    /**
     * 打榜详情
     */
    public function store_info(){
        $store_id = $this->request->param('store_id', '');
        if(empty($store_id)){
            $this->error("参数错误");
        }
        $data = model('Store')->where('id', $store_id)->field('id,name,logo,weigh, ticket, ticket_money as money, if_ticket')->find();
        if(empty($data)){
            $this->error("分会不存在");
        }
        $data['logo'] = getRealImg($data['logo']);
        /*$count = 0;
        $money = 0;*/
        // 排行
        // 该分会有人支持
        /*if(model('Order')->where('store_id', $store_id)->where('is_cancel', Order::IS_CANCEL_NOT)->where('is_paid', Order::IS_PAID_PAY)->count()){
            // 票数
            $ticket = model('Order')
                ->where('store_id', $store_id)
                ->where(function($query){
                    $query->whereOr('is_paid', Order::IS_PAID_PAY);
                })->where('is_cancel', Order::IS_CANCEL_NOT)
                ->field('count(*) as ticket, sum(money) as money')
                ->find();
            $count = $ticket['ticket'];
            $money = $ticket['money'];
            // 票数大于等于当前分会的
            $rank = model('Order')->alias('o')
                ->join('Store s', 'o.store_id=s.id')
                ->whereNull('s.delete_time')
                ->where(function($query){
                    $query->whereOr('is_paid', Order::IS_PAID_PAY);
                })->where('o.is_cancel', Order::IS_CANCEL_NOT)
                ->group('o.store_id')
                ->having('count(*) >= '.$count)
                ->count();
            if($rank > 1){
                // 票数等于当前分会并排序小于当前分会、id大于当前分会的
                $rank1 = model('Order')->alias('o')
                    ->join('Store s', 'o.store_id=s.id')
                    ->whereNull('s.delete_time')
                    ->where(function($query) use($data){
                        $query->whereOr('s.weigh', '>', $data['weigh'])->whereOr(function($q) use ($data){
                            $q->where('s.id', '<=', $data['id'])->where('s.weigh', '=', $data['weigh']);
                        });
                    })->where(function($query){
                        $query->whereOr('is_paid', Order::IS_PAID_PAY);
                    })->where('o.is_cancel', Order::IS_CANCEL_NOT)
                    ->group('o.store_id')
                    ->having('count(*) = '.$count)
                    ->count();
                $rank -= $rank1;
            }
        }else {
            $not_store_ids = model('Order')->alias('o')->join('Store s', 'o.store_id=s.id')
                ->whereNull('s.delete_time')
                ->where('o.is_cancel', Order::IS_CANCEL_NOT)->where('o.is_paid', Order::IS_PAID_PAY)->group('o.store_id')->column('o.store_id');
            $rank = count($not_store_ids);
            $rank1 = model('Store')->where(['id' => ['not in', $not_store_ids]])
                ->where(function ($query) use ($data) {
                    $query->whereOr('weigh', '>', $data['weigh'])->whereOr(function ($q) use ($data) {
                        $q->where('id', '<=', $data['id'])->where('weigh', '=', $data['weigh']);
                    });
                })->count();
            $rank += $rank1;
        }*/

        $rank = model('Store')
            ->where('if_ticket', Store::IF_TICKET_YES)
            ->where(function($query) use ($data){
            $query->whereOr('ticket', '>', $data['ticket'])->whereOr(function($que) use ($data){
                $que->where('ticket', $data['ticket'])->where(function($qu) use ($data){
                    $qu->whereOr('weigh', ">", $data['weigh'])->whereOr(function($q) use ($data){
                        $q->where('id', '<=', $data['id'])->where('weigh', '=', $data['weigh']);
                    });
                });
            });
        })->count();
        $data['rank'] = $rank;

        $data['is_ticket'] = 0; // 是否已支持 1 是 0 否
        if($this->auth->isLogin()){
            $data['is_ticket'] = model('Order')
                ->where('user_id', $this->auth->id)
                //->where('store_id', $store_id)
                ->where('is_paid', Order::IS_PAID_PAY)
                ->where('is_cancel', Order::IS_CANCEL_NOT)
                ->count();
        }
        /*$data['ticket'] = $count;
        $data['money'] = $money;*/

        unset($data['weigh']);

        $this->success('获取成功', $data);
    }

    // 支持人数列表
    public function get_ticket_user_list()
    {
        $store_id = $this->request->param('store_id', '');
        if(empty($store_id)){
            $this->error("参数错误");
        }
        $store = Store::get($store_id);
        if(empty($store)){
            $this->error("分会不存在");
        }
        $list = model('Order')->alias('o')
            ->join('User u', 'o.user_id=u.id')
            ->where('o.store_id', $store_id)
            ->where('o.is_cancel', Order::IS_CANCEL_NOT)
            ->where(function($query){
                $query->whereOr('is_paid', Order::IS_PAID_PAY);
            })->field('u.avatar,u.nickname,o.money,o.pay_time,o.id as order_id')
            ->order('o.pay_time desc')
            ->paginate($this->pagenum);
        foreach($list as &$item){
            $item['avatar'] = getRealImg($item['avatar']);
            $item['pay_time_text'] = date('Y/m/d H:i:s', $item['pay_time']);
        }
        $this->success("获取成功", $list);
    }

    // 支持页面
    public function ticket_html(){
        $store_id = $this->request->get('store_id', '');
        if(empty($store_id)){
            $this->error("参数错误");
        }
        $store = Store::get($store_id);
        if(empty($store)){
            $this->error("分会不存在");
        }
        $data['name'] = $store['name'];
        $data['logo'] = getRealImg($store['logo']);
        $data['money_list'] = [
            [
                'money'     => 1,
                'name'      => '1元',
            ],
            [
                'money'     => 8,
                'name'      => '8元',
            ],
            [
                'money'     => 18,
                'name'      => '18元',
            ],
            [
                'money'     => 58,
                'name'      => '58元',
            ],
            [
                'money'     => 88,
                'name'      => '88元',
            ],
            [
                'money'     => 188,
                'name'      => '188元',
            ],
        ];
        $this->success("获取成功", $data);
    }

    // 下单支付 汇付
    public function create_order(){
        $money = $this->request->post('money', 0);
        $store_id = $this->request->post('store_id', '');
        $comment = $this->request->post('comment', ''); // 留言
        $user_id = $this->auth->id;
        if(empty($store_id)){
            $this->error("参数错误");
        }
        if($money < 1){
            $this->error("支持金额不能低于1元");
        }
        if(model('Order')->where('user_id', $this->auth->id)->where('is_cancel', Order::IS_CANCEL_NOT)->where('is_paid', Order::IS_PAID_PAY)->count()){
            $this->error("您已支持，不能重复投票");
        }
        /*if(model('Order')->where('user_id', $this->auth->id)->where('store_id', $store_id)->where('is_cancel', Order::IS_CANCEL_NOT)->where('is_paid', Order::IS_PAID_PAY)->count()){
            $this->error("已支持该分会");
        }*/
        $store = Store::get($store_id);
        if(empty($store)){
            $this->error("所支持的分会不存在");
        }
        if($store['if_ticket'] == Store::IF_TICKET_NOT){
            $this->error("该分会不支持投票");
        }
        $order_sn = Order::create_order_sn();
        $params['money'] = $money;
        $params['order_sn'] = $order_sn;
        $params['third_order_sn'] = $order_sn;
        $params['user_id'] = $user_id;
        $params['store_id'] = $store_id;
        $params['pay_method'] = Order::PAY_METHOD_WECHAT; // 微信支付
        $params['is_paid'] = Order::IS_PAID_WAIT;
        $params['pay_time'] = 0;
        $params['is_cancel'] = Order::IS_CANCEL_NOT;
        $params['cancel_time'] = 0;
        $params['cancel_remark'] = '';
        $params['comment'] = $comment;
        $params['expiration_time'] = Order::getExpirationTime(); // 支付过期时间

        $pay_type = Config::getConfigValue('pay_type');

        Db::startTrans();
        try{
            $wemini_appid = Config::getConfigValue('miniapp_wechat_appid');
            if(empty($wemini_appid)){
                throw new Exception("请联系管理员配置微信参数");
            }
            $openid = Third::where('user_id', $this->auth->id)->where('platform', 'wemini')->value('openid');
            if(empty($openid)){
                throw new Exception("请先授权微信信息");
            }

            $order = Order::create($params);

            $title = "支持分会:".$store['name'];
            $money = sprintf('%.2f', $order['money']);

            if($pay_type == 1){
                // 微信支付
                $returnData = WechatPay::createOrder($title, $order_sn, $money, $openid);
                $returnData['money'] = $order['money'];
            }else{
                $ip = request()->ip();
                // 汇付支付回调地址
                $notify_url = Config::getConfigValue('adapay_notify_url');
                // 汇付应用ID
                $app_id = Config::getConfigValue('adapay_app_id');
                if(empty($notify_url) || empty($app_id)){
                    throw new Exception("请联系管理员配置支付参数");
                }
                $payment_params['pay_channel'] = 'wx_lite'; // wx_lite 微信小程序   wx_pub 微信公众号
                $payment_params['money'] = $money;
                $payment_params['app_id'] = $app_id;
                $payment_params['order_sn'] = $order_sn;
                $payment_params['title'] = $title;
                $payment_params['goods_desc'] = $title; // 商品描述信息
                $payment_params['ip'] = $ip;
                $expend['open_id'] = $openid;

                $payment_params['expend'] = $expend; // 额外参数
                $payment_params['notify_url'] = getRealImg($notify_url);

                $adapayReturnData = Payment::create_order($payment_params);
                OrderThird::create(['order_id'=>$order->id, 'third_order_sn'=>$order_sn, 'third_return_data' => json_encode($adapayReturnData), 'third_payment_id' => $adapayReturnData['id'], 'target_type' => OrderThird::TYPE_PAY]);
                //var_dump("adapay支付返回参数");
                //var_dump($returnData);
                $returnData['order_data'] = json_decode($adapayReturnData['expend']['pay_info'], true);
                /*if($returnData['appId'] != $wemini_appid){
                    throw new Exception("请联系管理员配置正确的微信参数");
                }*/
                $returnData['order_sn'] = $order_sn;
                $returnData['money'] = $order['money'];
            }
            Db::commit();
        }catch(Exception $e){
            Db::rollback();
            $this->error($e->getMessage(), '', $e->getCode());
        }
        $this->success("创建成功", $returnData);
    }
    // 支付回调 汇付
    public function pay_notify(){
        $params = $this->request->post();
        \AdaPay\AdaPay::init(APP_PATH. "common/library/payment/config/merchantConfig.json", "live");

//        $container = ApplicationContext::getContainer();
//        $loggerFactory = new LoggerFactory($container);
//        $logger = $loggerFactory->get('log', 'default');
        \AdaPay\AdaPay::writeLog("############# 回调返回参数");
        \AdaPay\AdaPay::writeLog(json_encode($params));
//        $logger->info("############# 回调返回参数");
//        $logger->info(json_encode($params));
        Db::startTrans();
        try{
            //验签请参data
            $data_str = $params["data"];
            \AdaPay\AdaPay::writeLog("############# 回调返回参数 data");
            \AdaPay\AdaPay::writeLog($data_str);
            //验签请参sign
            $sign = isset($params["sign"]) ? $params["sign"] : '';
            if($sign){
                Payment::verifySign($data_str, $sign);
            }

            $data = json_decode($data_str, true);
            switch($params['type']){
                case 'payment.succeeded':
                    \AdaPay\AdaPay::writeLog("----------支付成功 回调开始-----------");
                    // 支付成功
                    $order_id = OrderThird::where('third_order_sn', $data['order_no'])->where('target_type', OrderThird::TYPE_PAY)->value('order_id');
                    if(!empty($order_id)){
                        $order = Order::get($order_id);
                        if(!empty($order)){
                            Order::paySuccess($order);
                        }else{
                            // $logger->info("订单id order_id:".$order_id."      不存在");
                            \AdaPay\AdaPay::writeLog("订单id order_id:".$order_id."      不存在");
                        }
                    }else{
                        // $logger->info("订单号 third_order_sn:".$data['order_no']."      不存在");
                        \AdaPay\AdaPay::writeLog("订单号 third_order_sn:".$data['order_no']."      不存在");
                    }
                    break;
                case 'payment.failed':
                    // 支付失败
                    break;
                case 'payment.close.succeeded':
                    // 支付关单成功
                    break;
                case 'payment.close.failed':
                    // 支付关单失败
                    break;
            }
            Db::commit();
        }catch (Exception $e){
            Db::rollBack();
//            $logger->info("回调错误:".$e->getMessage()."      code:".$e->getCode()."       file:".$e->getFile()."   line:".$e->getLine());
            \AdaPay\AdaPay::writeLog("回调错误:".$e->getMessage()."      code:".$e->getCode()."       file:".$e->getFile()."   line:".$e->getLine());
            $this->error($e->getMessage(),[],$e->getCode());
        }

        // TODO 判断订单类型 是否需要调第三方回调
//        $logger->info("########回调成功结束");
        $this->success('异步回调响应成功');
    }

    // 取消订单
    public function order_cancel(){
        $order_sn = $this->request->post('order_sn');
        $remark = $this->request->post('remark', '用户主动取消');
        $user_id = $this->auth->id;
        if(empty($order_sn)){
            $this->error("参数错误");
        }
        if(empty($remark)){
            $this->error("参数错误");
        }
        try{
            $user = User::where('id', $this->auth->id)->find();
            if (empty($user)) {
                throw new Exception('该用户不存在');
            }
            $order = Order::where('order_sn', $order_sn)->find();
            if (empty($order)) {
                throw new Exception('该订单不存在');
            }
            if($order['user_id'] != $user_id){
                throw new Exception('该订单不是自己的');
            }
            if($order['is_paid'] == Order::IS_PAID_PAY){
                throw new Exception('该订单已支付，不能取消');
            }
            Order::cancel_order($order, $remark);
        }catch(Exception $e){
            $this->error($e->getMessage());
        }

        $this->success('该订单取消成功');
    }

    // 微信下单支付
    public function wechat_create_order(){
        $money = $this->request->post('money', 0);
        $store_id = $this->request->post('store_id', '');
        $comment = $this->request->post('comment', ''); // 留言
        $user_id = $this->auth->id;
        if(empty($store_id)){
            $this->error("参数错误");
        }
        if($money < 1){
            $this->error("支持金额不能低于1元");
        }
        if(model('Order')->where('user_id', $this->auth->id)->where('store_id', $store_id)->where('is_cancel', Order::IS_CANCEL_NOT)->where('is_paid', Order::IS_PAID_PAY)->count()){
            $this->error("已支持该分会");
        }
        $store = Store::get($store_id);
        if(empty($store)){
            $this->error("所支持的分会不存在");
        }
        $order_sn = Order::create_order_sn();
        $params['money'] = $money;
        $params['order_sn'] = $order_sn;
        $params['third_order_sn'] = $order_sn;
        $params['user_id'] = $user_id;
        $params['store_id'] = $store_id;
        $params['pay_method'] = Order::PAY_METHOD_WECHAT; // 微信支付
        $params['is_paid'] = Order::IS_PAID_WAIT;
        $params['pay_time'] = 0;
        $params['is_cancel'] = Order::IS_CANCEL_NOT;
        $params['cancel_time'] = 0;
        $params['cancel_remark'] = '';
        $params['comment'] = $comment;
        $params['expiration_time'] = Order::getExpirationTime(); // 支付过期时间

        Db::startTrans();
        try{
            $wemini_appid = Config::getConfigValue('miniapp_wechat_appid');
            if(empty($wemini_appid)){
                throw new Exception("请联系管理员配置微信参数");
            }
            $openid = Third::where('user_id', $this->auth->id)->where('platform', 'wemini')->value('openid');
            if(empty($openid)){
                throw new Exception("请先授权微信信息");
            }

            $order = Order::create($params);
            $money = sprintf('%.2f', $order['money']);

            $title = "支持分会:".$store['name'];

            $returnData = WechatPay::createOrder($title, $order_sn, $money, $openid);

            Db::commit();
        }catch(Exception $e){
            Db::rollback();
            $this->error($e->getMessage(), '', $e->getCode());
        }
        $this->success("创建成功", $returnData);
    }
}
